<template>
  <el-container style="height: 500px; border: 1px solid #eee">
    <el-aside width="280px" class="left-tree">
      <el-row>
        <el-col :span="6" class="custom-label">
          <span>组织体系:</span>
        </el-col>
        <el-col :span="18">
          <el-select v-model="orgTypeValue" clearable size="small" class="custom-select" @change="handleChange">
            <el-option v-for="item in orgTypeOptions" :key="item.value" :value="item.value" :label="item.label" />
          </el-select>
        </el-col>
      </el-row>
      <el-tree lazy node-key="id" ref="tree" :props="props" :load="loadNode" :render-content="renderContent" :highlight-current="true" :expand-on-click-node="false" @node-click="handleNodeClick" />
    </el-aside>
    <el-main style="padding:5px">
      <os-table autoHeight stripe :otherSearch="otherSearch" action="system/orgPage" ref="osTable" v-loading="loading" pageNumField="pageNo" :columns="columns" :form="form" :btn="btn" size="small" border>
      </os-table>
    </el-main>
  </el-container>
</template>
<script>
// import { mapGetters } from 'vuex'
export default {
  name: 'OrganizationPage',
  data () {
    return {
      props: {
        label: 'orgName',
        children: 'children',
        isLeaf: 'leaf'
      },
      form: {
        rule: [
          { type: 'Input', title: '组织名称', field: 'orgName' },
          { type: 'Input', title: '组织编号', field: 'orgCode' },
          { type: 'el-button', field: 'search', props: { type: 'primary' }, children: ['查询'], emit: ['click'] },
          { type: 'el-button', field: 'clear', props: { type: 'primary' }, children: ['清空'], emit: ['click'] }
        ]
      },
      btn: [
        { text: '新增', cb: () => this.onAdd() }
      ],
      columns: [
        { type: 'index', align: 'center', label: '序号' },
        { label: '组织名称', prop: 'orgName', width: 250 },
        { label: '组织编号', prop: 'orgCode' },
        { label: '电话', prop: 'phone' },
        { label: '邮箱', prop: 'email', width: 110 },
        {
          label: '状态',
          prop: 'validation',
          width: 50,
          formatter: (row) => {
            return this.$c.dictCode.status.find(i => i.value === row.validation).label
          }
        },
        {
          label: '操作',
          prop: 'action',
          fixed: 'right',
          width: 150,
          headerAlign: 'center',
          align: 'center',
          renderCell: (data) => (
            <div>
              <el-button
                type="text"
                size="mini"
                onClick={() => this.onEdit(data)}
              >
                编辑
              </el-button>
              <el-button
                type="text"
                size="mini"
                onClick={() => this.onDel(data)}
              >
                删除
              </el-button>
            </div>
          )
        }
      ],
      fApi: null,
      rule: [
        { type: 'hidden', title: 'id', field: 'id' },
        { type: 'hidden', title: 'parentId', field: 'parentId' },
        { type: 'Input', title: '父组织名称', field: 'parentName' },
        { type: 'Input', title: '组织名称', field: 'orgName', validate: [this.$v.required()] },
        { type: 'Input', title: '组织编号', field: 'orgCode' },
        { type: 'Input', title: '中文缩写', field: 'orgNameAbbr' },
        { type: 'Input', title: '英文缩写', field: 'orgNameEn' },
        { type: 'Radio', title: '状态', field: 'validation' },
        {
          type: 'select',
          title: '组织体系',
          field: 'orgTypeId',
          props: { filterable: true },
          col: { span: 16 },
          options: [], // 这里必须要有，不然不会显示结果
          validate: [this.$v.required()]
        },
        { type: 'Input', title: '电话', field: 'phone', validate: [this.$v.tel()] },
        { type: 'Input', title: '邮箱', field: 'email', validate: [this.$v.email()] },
        { type: 'Input', title: '地址', field: 'address' },
        { type: 'Input', field: 'description', title: '描述', props: { type: 'textarea' }, col: { span: 24 } }
      ],
      option: {
        ...this.$utils.formOptions(),
        mounted: $f => {
          this.$utils.setOptions($f, 'orgTypeId', 'typeName', 'id', 'system/orgTypeList')
          this.$utils.updateFormOptions($f, 'validation', this.$c.dictCode.status)
        }
      },
      loading: false,
      orgTypeValue: '',
      orgTypeOptions: [],
      otherSearch: { parentId: '-1', orgTypeId: this.orgTypeValue },
      node_had: '',
      resolve_had: '',
      treeRootData: { orgName: '组织机构', id: '-1', children: [] },
      parentData: {} // 点击后的父节点数据,主要用于增、修、删
    }
  },
  mounted () {
    // ...mapGetters('system')
    this.getOrgTypeData()
  },
  methods: {
    /** 获取数据 */
    async loadNode (node, resolve) {
      if (node.level === 0) {
        this.parentData = this.treeRootData
        this.node_had = node
        this.resolve_had = resolve
        return resolve([this.treeRootData])
      }
      // if (node.level > 1) return resolve([])
      let parentId = this.treeRootData.id
      if (node) {
        parentId = node.data.id
      }
      const { data } = await this.$store.dispatch('system/getOrgByParentId', { parentId: parentId, orgTypeId: this.orgTypeValue })
      node.data.children = [...data]
      resolve(data)
    },
    handleNodeClick (data, node) {
      this.parentData = data
      if (data) {
        this.otherSearch.parentId = data.id
      } else {
        this.otherSearch.parentId = this.treeRootData.id
      }
      this.$refs.osTable.getData()
    },
    async getOrgTypeData () {
      const { data } = await this.$store.dispatch('system/orgTypeList')
      const options = data.map(item => ({ label: item.typeName, value: item.id }))
      this.orgTypeOptions = [...options]
    },
    handleChange (val) {
      this.orgTypeValue = val
      // 重置树显示
      this.node_had.childNodes = []
      this.loadNode(this.node_had, this.resolve_had)
      this.parentData = this.treeRootData
      // 重置表格查询条件与表格显示
      this.otherSearch.orgTypeId = val
      this.otherSearch.parentId = this.treeRootData.id
      this.$refs.osTable.getData()
    },
    onAdd () {
      const nodeData = this.parentData // this.$refs.tree.getCurrentNode()
      if (!nodeData) {
        this.$utils.message.warning('请选择父节点！')
        return
      }
      this.handleData(null, nodeData)
    },
    async onEdit ({ row }) {
      this.handleData(row, this.parentData)
    },
    handleData (row, nodeData) {
      const btn = [{ text: '保存', loading: true, cb: cb => this.save(cb, row) }]
      const o = {}
      for (const item of this.rule) {
        o[item.field] = null
      }
      this.$utils.dialog(`${row ? '编辑' : '添加'}组织机构`, <form-create vModel={this.fApi} rule={this.rule} option={this.option} />, { btn })
      this.$nextTick(() => {
        this.$f.resetFields(this.fApi, row)
        if (row) {
          if (nodeData.id === '-1') {
            this.fApi.setValue({ parentName: nodeData.orgName })
          }
        } else {
          this.fApi.setValue({ parentId: nodeData.id, parentName: nodeData.orgName, validation: '1' })
          if (this.orgTypeValue != null && this.orgTypeValue !== '') {
            this.fApi.setValue({ orgTypeId: this.orgTypeValue })
          }
        }
        this.fApi.disabled(true, 'parentName')
      })
    },
    async onDel ({ row }) {
      const re = await this.$utils.confirm('确认要删除吗？')
      if (!re) return
      const { error } = await this.$store.dispatch('system/orgDelete', row.id)
      if (!error) {
        this.$utils.message.success('删除成功')
        this.$refs.osTable.getData()
        this.removeTreeNode(row, this.parentData)
      }
    },
    save (cb, row) {
      this.fApi.validate(async (valid) => {
        cb()
        if (valid) {
          const formData = this.fApi.formData()
          formData.id = row?.id
          const action = row ? 'system/orgUpdate' : 'system/orgInsert'
          const { data } = await this.$store.dispatch(action, formData)
          // console.info(action + '-----------formData: ' + JSON.stringify(formData))
          if (data) {
            this.$utils.message.success('保存成功')
            this.fApi.resetFields()
            this.$utils.hideDialog()
            this.$refs.osTable.getData()
            if (row) {
              this.updateTreeNode(this.parentData, data, row)
            } else {
              this.appendTreeNode(this.parentData, data)
            }
          }
        } else {
          console.log('表单校验失败')
        }
      })
    },
    appendTreeNode (parentData, data) {
      if (!parentData.children) {
        this.$set(parentData, 'children', [])
      }
      parentData.children.push(data)
    },
    updateTreeNode (parentData, newData, oldData) {
      if (!parentData || !parentData.children) {
        return
      }
      const children = parentData.children
      const index = children.findIndex(d => d.id === oldData.id)
      children.splice(index, 1)
      this.$refs.tree.remove(oldData)
      parentData.children.push(newData)
    },
    removeTreeNode (data, parentData) {
      // const parentNode = node.parent
      // const children = parentNode.data.children || parentNode.data
      if (!parentData || !parentData.children) {
        return
      }
      const children = parentData.children
      const index = children.findIndex(d => d.id === data.id)
      children.splice(index, 1)
      this.$refs.tree.remove(data)
    },
    renderContent (h, { node, data, store }) {
      return (
        <span class='custom-tree-node'>
          <span>{node.label}</span>
        </span>)
    }
  }
}
</script>
<style lang="scss" scoped>
.left-tree {
  background-color: #fff ;
  border : 1px solid #eee ;
  margin: 5px;
}
.custom-label {
  padding-left: 5px;
  padding-top: 10px ;
  font-size: 12px;
  color:#333333;
}
.custom-select {
  margin-top: 5px ;
  width: 98%;
  font-size: 12px;
}
</style>
